import axios, { AxiosResponse } from 'axios'
import cookie from 'js-cookie'
import { ElMessage } from 'element-plus'
import { useProfileStore } from '@/store/profile'

class AuthService {
  private accessToken: string | null = null
  private isRefreshing = false
  private failedQueue: Array<{
    resolve: (value?: any) => void
    reject: (reason?: any) => void
  }> = []

  constructor() {
    // 从cookie中获取初始token
    this.accessToken = cookie.get('token') || null
    this.setupAutoRefresh()
  }

  // 处理请求，添加token
  async processRequest(config: any) {
    // 检查token是否即将过期
    if (this.isTokenExpiringSoon()) {
      // 等待token刷新完成
      await this.refreshTokenIfNeeded()
    }

    // 添加token到请求头
    if (this.accessToken) {
      config.headers.Authorization = this.accessToken
    }
    return config
  }

  // 检查token是否即将过期（5分钟内）
  isTokenExpiringSoon() {
    if (!this.accessToken) return true

    try {
      // 解析JWT token获取过期时间
      const payload = JSON.parse(atob(this.accessToken.split('.')[1]))
      const exp = payload.exp
      const now = Math.floor(Date.now() / 1000)

      // 如果距离过期时间小于5分钟，则需要刷新
      return exp - now < 300
    } catch (error) {
      // token解析失败，当作即将过期处理
      return true
    }
  }

  // 如果需要则刷新token
  async refreshTokenIfNeeded() {
    if (this.isRefreshing) {
      // 如果正在刷新token，则返回一个Promise等待刷新完成
      return new Promise((resolve, reject) => {
        this.failedQueue.push({ resolve, reject })
      })
    }

    // 检查是否有token且即将过期
    if (this.accessToken && this.isTokenExpiringSoon()) {
      this.isRefreshing = true
      try {
        await this.refreshAccessToken()
      } finally {
        this.isRefreshing = false

        // 处理队列中的请求
        while (this.failedQueue.length) {
          const { resolve, reject } = this.failedQueue.shift()!
          if (this.accessToken) {
            resolve(this.accessToken)
          } else {
            reject(new Error('Token刷新失败'))
          }
        }
      }
    }
  }

  // 刷新access token
  async refreshAccessToken() {
    try {
      // 在刷新请求中也需要带上当前的token
      const response: AxiosResponse<{ code: number; data: string; msg?: string }> = await axios.get(
        `${import.meta.env.VITE_API_BASE_URL}/accounts/refresh`,
        {
          headers: {
            Authorization: this.accessToken || '',
          },
        },
      )

      if (response.data.code === 200) {
        this.accessToken = response.data.data
        cookie.set('token', this.accessToken)
        console.log('Token 刷新成功')
        return this.accessToken
      } else {
        throw new Error(response.data.msg || 'Token刷新失败')
      }
    } catch (error) {
      console.error('Token 刷新失败:', error)
      // 刷新失败，需要重新登录
      this.logout()
      throw error
    }
  }

  // 登录
  async login(credentials: {
    username?: string
    phone?: string
    email?: string
    password: string
  }) {
    try {
      const response: AxiosResponse<{ code: number; data: string; msg?: string }> =
        await axios.post(`${import.meta.env.VITE_API_BASE_URL}/accounts/login`, credentials)

      if (response.data.code === 200) {
        this.accessToken = response.data.data
        cookie.set('token', this.accessToken)
        return response.data
      } else {
        throw new Error(response.data.msg || '登录失败')
      }
    } catch (error) {
      this.accessToken = null
      cookie.remove('token')
      throw error
    }
  }

  // 登出
  logout() {
    this.accessToken = null
    cookie.remove('token')

    // 调用后端登出接口清理cookie
    axios.post(`${import.meta.env.VITE_API_BASE_URL}/accounts/logout`).catch(() => {
      // 忽略登出错误
    })

    // 更新store状态，使用标志防止循环调用
    const profileStore = useProfileStore()
    if (profileStore.isLoggedIn) {
      profileStore.logoutWithoutAuth() // 使用特殊方法避免循环调用
    }
  }

  // 设置自动刷新token
  setupAutoRefresh() {
    // 每10分钟检查一次是否需要刷新token
    setInterval(
      async () => {
        if (this.accessToken) {
          if (this.isTokenExpiringSoon()) {
            try {
              await this.refreshTokenSilently()
            } catch (error) {
              console.warn('Token refresh failed:', error)
            }
          }
        }
      },
      10 * 60 * 1000,
    ) // 10分钟
  }

  // 静默刷新token
  async refreshTokenSilently() {
    // 静默刷新，不影响用户操作
    const newToken = await this.refreshAccessToken()
    // 可以在这里添加其他需要更新应用状态的逻辑
    return newToken
  }

  // 获取当前token
  getToken() {
    return this.accessToken
  }
}

// 创建authService单例
const authService = new AuthService()

export default authService
